#include "image.h"

template<class T> 
ImageTexture<T>::ImageTexture(	Reference<TextureMap> m, 
								const string &filename, 
								bool doTrilinear, 
								float maxAniso, 
								ImageWrap wrapMode) {
	mapping = m;
	mipmap = GetTexture(filename, doTrilinear, maxAniso, wrapMode);
}

template<class T>
ImageTexture<T>::~ImageTexture() {
	mapping = NULL;
}

template<class T>
MIPMap<T> *
ImageTexture<T>::GetTexture(const string &filename, 
							bool doTrilinear, 
							float maxAniso, 
							ImageWrap wrap) {

	// Look for texture in texture cache
	TexInfo texInfo(filename, doTrilinear, maxAniso, wrap);
	if(textures.find(texInfo) != textures.end())
		return textures[texInfo];

	// Not found, read image
	int width, height;
	Spectrum *texels = ReadImage(filename, &width, &height);
	MIPMap<T> *ret = NULL;
	if(texels) {
		// Convert to T
		T *convertedTexels = new T[width * height];
		for(int i = 0; i < width * height; i++)
			convert(texels[i], &convertedTexels[i]);
		ret = new MIPMap<T>(width, height,convertedTexels, doTrilinear, maxAniso, wrap);
		SAFE_DELETE_ARRAY(texels);
		SAFE_DELETE_ARRAY(convertedTexels);
	}
	else {
		T *oneVal = new T[1];
		oneVal[0] = 1;
		ret = new MIPMap<T>(1,1,oneVal);
		SAFE_DELETE_ARRAY(oneVal);
	}

	// put mipmap in texture cache
	textures[texInfo] = ret;

	return ret;
}

template<class T>
T ImageTexture<T>::Evaluate(const Intersection &isect) const {
	float s, t, dsdx, dtdx, dsdy, dtdy;
	mapping->map(isect, &s, &t, &dsdx, &dtdx, &dsdy, &dtdy);
	return mipmap->Lookup(s, t, dsdx, dtdx, dsdy, dtdy);
}